/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kylingroup.Desktop.Plugin.FileUploader.Flat;

import com.kylingroup.Desktop.Plugin.FileUploader.Bean.UploadListItem;
import com.kylingroup.Desktop.Plugin.FileUploader.Cell.UploadListCell;
import com.kylingroup.Desktop.Plugin.FileUploader.Task.LocalFileTransferTask;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.FadeTransition;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Separator;
import javafx.scene.control.Tooltip;
import javafx.scene.effect.Effect;
import javafx.scene.effect.MotionBlur;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.util.Duration;

/**
 *
 * @author kylin
 */
public class LocalFlatView implements FlatView{
    private VBox flatviewbox=null;
    private HBox navigator=null;
    private HBox btnBox=null;
    private ImageView btnSwitch=null;
    private int navindex=0;
    private ScrollPane flatview=null;
    private ListView<UploadListItem> uploadList=null; 
    private int row=0,col=0;
    private GridPane grid=null;
    private boolean isFlat=true;
    private String currentPath;
    private ArrayList<String> alreadydragged=new ArrayList<String>();

    public LocalFlatView(VBox flatviewbox){
        this.flatviewbox=flatviewbox;
        
        navigator=new HBox();
        navigator.setAlignment(Pos.CENTER_LEFT);
        navigator.setPrefHeight(30);
        navigator.autosize();
        navigator.setMinHeight(30);
 
        flatview=new ScrollPane();
        VBox.setVgrow(flatview,Priority.ALWAYS);
        
        grid=new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setPadding(new Insets(5,5,5,5));
        grid.setVgap(5);
        grid.setHgap(5);
        
        btnBox=new HBox();
        btnBox.setAlignment(Pos.CENTER_RIGHT);
        btnBox.setPadding(new Insets(0,10,5,10));
        HBox.setHgrow(btnBox, Priority.ALWAYS);
        
        MotionBlur motionBlur = new MotionBlur();
        motionBlur.setRadius(3.2);
        motionBlur.setAngle(92.1);
        
        
        btnSwitch=new ImageView(new Image(this.getClass().getResourceAsStream("upload.png")));
        btnSwitch.setFitWidth(15);
        btnSwitch.setFitHeight(15);
        setImageButton(btnSwitch,"switchto", motionBlur);
        
        ImageView btnMkdir=new ImageView(new Image(this.getClass().getResourceAsStream("newfolder.png")));
        btnMkdir.setFitWidth(15);
        btnMkdir.setFitHeight(15);
        setImageButton(btnMkdir,"mkdir", motionBlur);
        
        HBox.setMargin(btnSwitch, new Insets(0,0,0,5));
        btnBox.getChildren().addAll(btnMkdir,btnSwitch);
        
    }
    
    public void show(String path){
        flatviewbox.getChildren().addAll(navigator,btnBox,flatview);
        iterator(path);
        initUploadList();
        bindDragActions();
    }
    
    public void createNavigator(String path){
        ObservableList<Node> children=navigator.getChildren();
        if(children.size()!=0){
            navigator.getChildren().removeAll(children);
        }
        
        String[] navs=path.substring(1, path.length()).split("/");
        String absoultpath="";

        for(navindex=0;navindex<navs.length;navindex++){            
            HBox bnav=new HBox();
            bnav.setAlignment(Pos.CENTER);
            bnav.setPadding(new Insets(5,5,5,5));
            Label lnav=new Label(navs[navindex]);
            //lnav.setPadding(new Insets(0,5,0,0));
            Separator sp=new Separator();
            sp.setOrientation(Orientation.VERTICAL);
            bnav.getChildren().addAll(lnav,sp);
            bnav.setId(String.valueOf(navindex));
            
            if(navindex==0){
                absoultpath="/"+navs[navindex];
                bnav.setUserData(absoultpath);
            }else{
                absoultpath=absoultpath+"/"+navs[navindex];
                bnav.setUserData(absoultpath);
            }
            
            lnav.setTooltip(new Tooltip(absoultpath));
            
            bnav.setOnMouseClicked(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent event){
                    navigator.getChildren().remove(Integer.parseInt(bnav.getId().toString())+1,navigator.getChildren().size());
                    LocalFlatView.this.iterator(bnav.getUserData().toString());
                }
            });                        
            navigator.getChildren().add(bnav);
        }
    }
    
    public void iterator(String path){
        currentPath=path;
        
        reset();
        
        File root=new File(path);
        
        if(root.exists()&&root.isDirectory()){
            
            createNavigator(root.getAbsolutePath());

            File files[]=root.listFiles();
            int index=0;
            
            if(files.length>0&&files.length<10){
                for(;index<files.length;index++){
                    col=index;
                    File sub=files[col];
                    FlatViewItem item=new FlatViewItem(LocalFlatView.this,currentPath);
                    item.setFile(sub);
                    item.setIsAdded(false);
                    grid.addColumn(col,item.getView());
                }
                flatview.setContent(grid);
            }else if(files.length>=10){
                while(true){        
                    if(index==files.length){
                        flatview.setContent(grid);
                        break;
                    }else{
                        if((index!=0)&&(index%10==0)){
                            row++;
                        }
                        File sub=files[index];
                        FlatViewItem item=new FlatViewItem(LocalFlatView.this,currentPath);
                        item.setFile(sub);
                        item.setIsAdded(false);
                        col=index%10;
                        grid.add(item.getView(), col,row);
                        index++;
                    }
                }
            }
        }
    }
    public void reset(){
        row=0;
        col=0;
        grid.getChildren().removeAll(grid.getChildren());
        flatview.setContent(null);
    }
    
    public void bindDragActions(){
        flatview.setOnDragOver(new EventHandler<DragEvent>(){
            public void handle(DragEvent event){
                if(event.getGestureSource()!=flatview&& event.getDragboard().hasFiles()) {
                    event.acceptTransferModes(TransferMode.COPY);
                }
                event.consume();
            }
        });
        
        flatview.setOnDragEntered(new EventHandler<DragEvent>(){
            public void handle(DragEvent event) {
                if(event.getGestureSource()!=flatview&&event.getDragboard().hasFiles()){
                    flatview.setOpacity(0.5);
                    FadeTransition fadeTransition = new FadeTransition(Duration.seconds(0.5),flatview);
                    fadeTransition.setFromValue(1);
                    fadeTransition.setToValue(0.5);
                    fadeTransition.setAutoReverse(false);
                    fadeTransition.play();
                }
                event.consume();
            }
        });

        flatview.setOnDragExited(new EventHandler<DragEvent>(){
            public void handle(DragEvent event){
                FadeTransition fadeTransition = new FadeTransition(Duration.seconds(0.5),flatview);
                fadeTransition.setFromValue(0.5);
                fadeTransition.setToValue(1);
                fadeTransition.setAutoReverse(false);
                fadeTransition.play();
                event.consume();
            }
        });

        flatview.setOnDragDropped(new EventHandler<DragEvent>(){
            public void handle(DragEvent event){
                Dragboard db=event.getDragboard();
                boolean success=false;
                if(db.hasFiles()){
                    ArrayList<File> files=(ArrayList<File>)db.getFiles();
                    appendFileView(files.get(0));
                    success = true;
                }
                event.setDropCompleted(success);
                event.consume();
            }
        });
    }
    
    public void appendFileView(File file){
        if(!alreadydragged.contains(file.getName())){
            
            UploadListItem item=new UploadListItem(file);
            item.setDestPath(currentPath);
            item.getBox().setUserData(file.getName());
            
            LocalFileTransferTask task=new LocalFileTransferTask(file,currentPath,item);
            item.setTransfertask(task);
            
            FlatViewItem fitem=new FlatViewItem(LocalFlatView.this,currentPath);
            fitem.setFile(file);
            fitem.setIsAdded(true);
            fitem.setUpitem(item);
            
            if(col<=8){
                col+=1;
                grid.add(fitem.getView(), col,row);   
            }else if(col>8){
                row=row+1;
                col=0;
                grid.add(fitem.getView(), col,row);
            }
            
            
            uploadList.getItems().add(item);
            uploadList.scrollTo(item);
            alreadydragged.add(file.getName());
        }else{
            alert("File already exist!");
        }
    }
    private void alert(String info){
        Alert alert=new Alert(Alert.AlertType.WARNING,"");
        alert.initModality(Modality.APPLICATION_MODAL);
        alert.initOwner(null);
        alert.getDialogPane().setContentText(info);
        alert.getDialogPane().setHeaderText(Alert.AlertType.WARNING.name());
        alert.showAndWait().filter(response -> response==ButtonType.OK).ifPresent(response -> System.out.println("The alert was approved"));
    }
    public void initUploadList(){
        uploadList=new ListView<UploadListItem>();
        VBox.setVgrow(uploadList, Priority.ALWAYS);
        uploadList.setCellFactory((ListView<UploadListItem> list) -> new UploadListCell(uploadList));
        uploadList.getSelectionModel().setSelectionMode(null);//.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
    }

//***************************************************************************************************************
    public void switchto(){
        if(isFlat==true){
            FadeTransition fade=new FadeTransition(Duration.seconds(0.5),flatview);
            fade.setFromValue(1);
            fade.setToValue(0.0);
            fade.setAutoReverse(false);
            fade.play();
            flatviewbox.getChildren().remove(flatview);    
            flatviewbox.getChildren().add(uploadList);
            FadeTransition show=new FadeTransition(Duration.seconds(0.5),uploadList);
            show.setFromValue(0.0);
            show.setToValue(1.0);
            show.setAutoReverse(false);
            show.play();
            btnSwitch.setImage(new Image(this.getClass().getResourceAsStream("flat.png")));
            isFlat=false;
        }else{
            FadeTransition fade=new FadeTransition(Duration.seconds(0.5),uploadList);
            fade.setFromValue(1);
            fade.setToValue(0.0);
            fade.setAutoReverse(false);
            fade.play();
            flatviewbox.getChildren().remove(uploadList);
            flatviewbox.getChildren().add(flatview);
            FadeTransition show=new FadeTransition(Duration.seconds(0.5),flatview);
            show.setFromValue(0.0);
            show.setToValue(1.0);
            show.setAutoReverse(false);
            show.play();
            btnSwitch.setImage(new Image(this.getClass().getResourceAsStream("upload.png")));
            isFlat=true;
        }
    }
    
    public void mkdir(){
        File newfolder=new File(currentPath+"/"+"newfolder");
        newfolder.mkdir();
        iterator(currentPath);
    }
    public void setImageButton(ImageView btn,String method,Effect effect){
        btn.setOnMouseClicked(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent event) {
                try {
                    LocalFlatView.this.getClass().getDeclaredMethod(method,null).invoke(LocalFlatView.this,null);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(LocalFlatView.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalArgumentException ex) {
                    Logger.getLogger(LocalFlatView.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(LocalFlatView.class.getName()).log(Level.SEVERE, null, ex);
                } catch (NoSuchMethodException ex) {
                    Logger.getLogger(LocalFlatView.class.getName()).log(Level.SEVERE, null, ex);
                } catch (SecurityException ex) {
                    Logger.getLogger(LocalFlatView.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        if(effect!=null){
            btn.setOnMouseEntered(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent event) {
                    btn.setEffect(effect);
                }
            });
            btn.setOnMouseExited(new EventHandler<MouseEvent>(){
                @Override
                public void handle(MouseEvent event) {
                    btn.setEffect(null);
                }
            });
        }
    }
}
